
let adsSymbol = Symbol("model#ads#symbol")
let applicationSymbol = Symbol("model#application#symbol")
let moduleApp = Symbol("model#moduleApp#symbol")
let keyword = Symbol("model#keyWord#symbol")
let empireStore = Symbol("model#empireStore#symbol")
let additionProp = Symbol("model#additionProp#symbol")
let tskList = Symbol("model#tskList#symbol")
let leaderboard = Symbol("model#leaderboard#symbol")
let channel = Symbol("model#channel#symbol")
let fs = require("fs")
const util = require("util")
const readAsync = util.promisify(fs.readFile)
let path = require("path")
class StaticCache {
	/** @param {import("egg").Application} app */
	constructor(app) {
		this.app = app
		this.initAds()
		this.initApplication()
		this.initModuleApplication()
		this.initKeyWord()
		this.initEmpireStore()
		this.initAdditionProp()
		this.initTaskListCache()
		this.initLeaderboard(),
		this.initChannel()
	}

	initAds() {
		let app = this.app
		let Ads = app.model.Ads
		Object.defineProperty(this.app.cache, "ads", {
			get() {
				if (this[adsSymbol])
					return this[adsSymbol]
				else {
					app.logger.warn("ads缓存不能命中")
					let ads = Ads.findAll(
						{raw: true}
					)
					this[adsSymbol] = ads
					return this[adsSymbol]
				}
			},
			set(v) {
				this[adsSymbol] = v
			}
		})
	}

	initApplication() {
		let app = this.app
		let Application = app.model.Application
		Object.defineProperty(this.app.cache, "application", {
			get() {
				if (this[applicationSymbol])
					return this[applicationSymbol]
				else {
					app.logger.warn("缓存不能命中")
					let application = Application.findAll(
						{raw: true}
					)
					this[applicationSymbol] = application
					return this[applicationSymbol]
				}
			},
			set(v) {
				this[applicationSymbol] = v
			}
		})
	}

	initModuleApplication() {
		let app = this.app
		let ModuleApplicat = app.model.ModuleApplicat
		let sym = moduleApp
		Object.defineProperty(this.app.cache, "moduleApplicat", {
			get() {
				if (this[sym])
					return this[sym]
				else {
					app.logger.warn("缓存不能命中")
					let mapp = ModuleApplicat.findAll(
						{raw: true}
					)
					this[sym] = mapp
					return this[sym]
				}
			},
			set(v) {
				this[sym] = v
			}
		})
	}

	initKeyWord() {
		let app = this.app
		let KeyWord = app.model.KeyWord
		let sym = keyword
		Object.defineProperty(this.app.cache, "keyWord", {
			get() {
				if (this[sym])
					return this[sym]
				else {
					app.logger.warn("缓存不能命中")
					let key = KeyWord.findAll(
						{raw: true}
					)
					this[sym] = key
					return this[sym]
				}
			},
			set(v) {
				this[sym] = v
			}
		})
	}

	initEmpireStore() {
		let app = this.app
		let EmpireStore = app.model.Game.EmpireStore
		let sym = empireStore
		Object.defineProperty(this.app.cache, "empireStore", {
			get() {
				if (this[sym])
					return this[sym]
				else {
					app.logger.warn("商店缓存不能命中")
					let es = EmpireStore.findAll(
						{raw: true}
					)
					this[sym] = es
					return this[sym]
				}
			},
			set(v) {
				this[sym] = v
			}
		})
	}

	initAdditionProp() {
		let app = this.app
		let AdditionProp = app.model.Game.AdditionProp
		let sym = additionProp
		Object.defineProperty(this.app.cache, "additionProp", {
			get() {
				if (this[sym])
					return this[sym]
				else {
					app.logger.warn("道具缓存不能命中")
					let es = AdditionProp.findAll(
						{raw: true}
					).then(v => {
						v.forEach((obj) => {
							try {
								obj.detail = JSON.parse(obj.detail)
							} catch (error) {
								obj.detail = {}
							}
							Object.freeze(obj) //防止改变数据
						})
						return v
					})
					this[sym] = es
					return this[sym]
				}
			},
			set(v) {
				this[sym] = v
			}
		})
	}

	initTaskListCache() {
		let sym = tskList
		let app = this.app
		Object.defineProperty(this.app.cache, "tskList", {
			get() {
				if (this[sym])
					return this[sym]
				else {
					app.logger.warn("任务缓存不能命中")
					let filePath = path.join(__dirname, "../../config/game/tsk.json")

					let file = readAsync(filePath).then((content) => {
						try {
							let obj = JSON.parse(content.toString())
							if (Array.isArray(obj))
								return obj
							else {
								return []
							}
							// app.validator()
						} catch (error) {
							app.logger.warn("读取配置出错")
							return []
						}
					})

					this[sym] = file
					return this[sym]
				}
			},
			set(v) {
				this[sym] = v
			}
		})

	}

	initLeaderboard() {
		let app = this.app
		let LeaderboardModel = app.model.Game.Leaderboard
		let ShopCount = app.model.GameView.ShopCount
		let Op = app.model.Op
		let sym = leaderboard
		Object.defineProperty(this.app.cache, "leaderboard", {
			get() {
				if (this[sym])
					return this[sym]
				else {
					app.logger.warn("排行版缓存不能命中")
					let lb = LeaderboardModel.findAll(
						{raw: true}
					).then(async leaderboards => {
						let oid2Index = {}// oid==>index
						let userOids = leaderboards.map((v, index) => {
							oid2Index[v.id] = index
							return v.id
						})
						let o = await ShopCount.findAll({
							where: {
								oid: {
									[Op.in]: userOids
								}
							}
						})
						o.forEach(v => {
							leaderboards[oid2Index[v.oid]].count = v.count
						})
						return leaderboards
					})
					this[sym] = lb
					return this[sym]
				}
			},
			set(v) {
				this[sym] = v
			}
		})
	}

	initChannel() {
		let app = this.app
		let Channel = app.model.Channel
		let sym = channel
		Object.defineProperty(this.app.cache, "channel", {
			get() {
				if (this[sym])
					return this[sym]
				else {
					app.logger.warn("渠道缓存不能命中")
					let es = Channel.findAll(
						{raw: true}
					)
					this[sym] = es
					return this[sym]
				}
			},
			set(v) {
				this[sym] = v
			}
		})
	}
}
module.exports = StaticCache